from pyasn1_modules import rfc5280
from pyasn1.type import univ, namedtype,char
from pyasn1.codec.der import encoder, decoder


# 定义 IssuerAndSerialNumber 类
class IssuerAndSerialNumber(univ.Sequence):
    componentType = namedtype.NamedTypes(
        namedtype.NamedType('issuer', rfc5280.Name()),
        namedtype.NamedType('serialNumber', rfc5280.CertificateSerialNumber())
    )


def create_issuer_and_serial_number(issuer_name, serial_number):
    """
    创建 IssuerAndSerialNumber 对象

    参数:
    issuer_name: 证书颁发者名称 (rfc5280.Name 对象)
    serial_number: 证书序列号 (整数或 pyasn1 的 Integer 对象)

    返回:
    IssuerAndSerialNumber 对象
    """
    # 创建 IssuerAndSerialNumber 对象
    issuer_and_serial = IssuerAndSerialNumber()

    # 设置 issuer 字段
    issuer_and_serial['issuer'] = issuer_name

    # 设置 serialNumber 字段
    # 如果 serial_number 是整数，转换为 pyasn1 的 Integer 对象
    if isinstance(serial_number, int):
        issuer_and_serial['serialNumber'] = univ.Integer(serial_number)
    else:
        issuer_and_serial['serialNumber'] = serial_number

    return issuer_and_serial


def build_issuer_name(country=None, organization=None, organizational_unit=None,
                      common_name=None):
    """
    构建证书颁发者名称 (rfc5280.Name 对象)

    参数:
    country: 国家代码 (如 'CN')
    organization: 组织名称
    organizational_unit: 组织单位名称
    common_name: 通用名称

    返回:
    rfc5280.Name 对象
    """
    # 创建 Name 对象 (实际上是 rfc5280.RDNSequence)
    name = rfc5280.Name()

    # 创建相对可分辨名称序列 (RDNSequence)
    rdn_sequence = rfc5280.RDNSequence()

    # 为每个属性创建相对可分辨名称 (RelativeDistinguishedName)
    rdn_index = 0

    # 添加国家属性 (C)
    if country:
        rdn = rfc5280.RelativeDistinguishedName()
        attribute_type_and_value = rfc5280.AttributeTypeAndValue()

        # 设置属性类型为国家 (C)
        attribute_type_and_value['type'] = rfc5280.id_at_countryName

        # 设置属性值
        attribute_value = char.PrintableString(country)
        attribute_type_and_value['value'] = attribute_value

        # 将属性添加到 RDN
        rdn.setComponentByPosition(0, attribute_type_and_value)

        # 将 RDN 添加到序列
        rdn_sequence.setComponentByPosition(rdn_index, rdn)
        rdn_index += 1

    # 添加组织属性 (O)
    if organization:
        rdn = rfc5280.RelativeDistinguishedName()
        attribute_type_and_value = rfc5280.AttributeTypeAndValue()

        # 设置属性类型为组织 (O)
        attribute_type_and_value['type'] = rfc5280.id_at_organizationName

        # 设置属性值
        attribute_value = char.UTF8String(organization)
        attribute_type_and_value['value'] = attribute_value

        # 将属性添加到 RDN
        rdn.setComponentByPosition(0, attribute_type_and_value)

        # 将 RDN 添加到序列
        rdn_sequence.setComponentByPosition(rdn_index, rdn)
        rdn_index += 1

    # 添加组织单位属性 (OU)
    if organizational_unit:
        rdn = rfc5280.RelativeDistinguishedName()
        attribute_type_and_value = rfc5280.AttributeTypeAndValue()

        # 设置属性类型为组织单位 (OU)
        attribute_type_and_value['type'] = rfc5280.id_at_organizationalUnitName

        # 设置属性值
        attribute_value = char.UTF8String(organizational_unit)
        attribute_type_and_value['value'] = attribute_value

        # 将属性添加到 RDN
        rdn.setComponentByPosition(0, attribute_type_and_value)

        # 将 RDN 添加到序列
        rdn_sequence.setComponentByPosition(rdn_index, rdn)
        rdn_index += 1

    # 添加通用名称属性 (CN)
    if common_name:
        rdn = rfc5280.RelativeDistinguishedName()
        attribute_type_and_value = rfc5280.AttributeTypeAndValue()

        # 设置属性类型为通用名称 (CN)
        attribute_type_and_value['type'] = rfc5280.id_at_commonName

        # 设置属性值
        attribute_value = char.UTF8String(common_name)
        attribute_type_and_value['value'] = attribute_value

        # 将属性添加到 RDN
        rdn.setComponentByPosition(0, attribute_type_and_value)

        # 将 RDN 添加到序列
        rdn_sequence.setComponentByPosition(rdn_index, rdn)

    # 将 RDNSequence 设置为 Name
    name.setComponentByName('rdnSequence', rdn_sequence)

    return name


# 示例使用
if __name__ == "__main__":
    # 构建证书颁发者名称
    issuer_name = build_issuer_name(
        country='CN',
        organization='Example Company',
        organizational_unit='IT Department',
        common_name='Example CA'
    )

    # 证书序列号
    serial_number = 1234567890

    # 创建 IssuerAndSerialNumber 对象
    issuer_and_serial = create_issuer_and_serial_number(issuer_name, serial_number)

    try:
        # 编码为 DER 格式
        der_data = encoder.encode(issuer_and_serial)

        # 打印 DER 编码的十六进制表示
        print("DER 编码:")
        print(der_data.hex())

        # 解码验证
        decoded, _ = decoder.decode(der_data, asn1Spec=IssuerAndSerialNumber())
        print("\n解码后的颁发者:")
        print(decoded['issuer'])
        print("解码后的序列号:")
        print(decoded['serialNumber'])
    except Exception as e:
        print(f"编码失败: {e}")